package com.sgb.kjwl.viewmodel.self.logistics;

import android.app.Application;
import android.content.Context;
import android.text.TextUtils;

import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.MutableLiveData;

import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.model.BitmapDescriptor;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.LatLngBounds;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.PolylineOptions;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.geocoder.GeocodeAddress;
import com.amap.api.services.geocoder.GeocodeQuery;
import com.amap.api.services.geocoder.GeocodeResult;
import com.amap.api.services.geocoder.GeocodeSearch;
import com.amap.api.services.geocoder.RegeocodeResult;
import com.amap.api.services.route.BusRouteResult;
import com.amap.api.services.route.DrivePath;
import com.amap.api.services.route.DriveRouteResult;
import com.amap.api.services.route.DriveStep;
import com.amap.api.services.route.RideRouteResult;
import com.amap.api.services.route.RouteSearch;
import com.amap.api.services.route.WalkRouteResult;
import com.sgb.alimaplibrary.MapMarkerTools;
import com.sgb.alimaplibrary.MarkerEntity;
import com.sgb.kjwl.R;
import com.sgb.kjwl.api.APIManager;
import com.sgb.kjwl.api.NewAPIManager;
import com.sgb.kjwl.model.entity.transport.BiddingOrderDetailsEntity;
import com.sgb.kjwl.model.entity.transport.OperateGoodsSourcePlaceVO;
import com.sgb.kjwl.model.entity.transport.common.AddressItem;
import com.sgb.kjwl.view.ui.activity.transport.BiddingOrderDetailsActivity;
import com.swgk.core.base.model.entity.BaseEntity;
import com.swgk.core.dialog.DialogHelper;
import com.swgk.core.util.MLog;
import com.swgk.core.util.MToast;

import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.List;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

import static com.sgb.kjwl.view.ui.activity.transport.BiddingOrderDetailsActivity.POSITION_DEST;

/**
 * Describe:
 * Author:  yangLei
 * Date:    2021/7/20
 */
public class BiddingOrderDetailsModel extends AndroidViewModel {
    public MutableLiveData<BiddingOrderDetailsEntity> detailsLD = new MutableLiveData<>();
    public MutableLiveData<LatLng> ldLatLng = new MutableLiveData<>();
    public MutableLiveData<Boolean> ldMapLoadFinish = new MutableLiveData<>();

    private BiddingOrderDetailsEntity orderEntity;
    //装卸点经纬度信息
    private List<LatLonPoint> sourcePoints = new ArrayList<>();
    //司机实时轨迹点信息
    //货源信息标记集合
    private String handleTypeNo;
    private RouteSearch planRouteSearch;
    private AMap aMap;
    private List<LatLng> latLngs = new ArrayList<>();
    private Context context;

    private MapMarkerTools mapMarkerTools;
    private List<AddressItem> bundles = new ArrayList<>();
    private List<AddressItem> addressPointList = new ArrayList<>();
    private List<Marker> markers = new ArrayList<>();
    public MutableLiveData<AddressItem> ldCurrAddress = new MutableLiveData<>();

    public MapMarkerTools getMapMarkerTools() {
        return mapMarkerTools;
    }

    public void setMapMarkerTools(MapMarkerTools mapMarkerTools) {
        this.mapMarkerTools = mapMarkerTools;
    }


    public BiddingOrderDetailsModel(@NonNull @NotNull Application application) {
        super(application);
        context = application;
    }

    /**
     * 获取竞价订单详情
     *
     * @param activity
     * @param isOwner
     * @param no
     */
    public void getDetails(BiddingOrderDetailsActivity activity, int isOwner, String no) {
        DialogHelper.showProgressDialog(activity, null, "数据加载中...", 0, false, null).setCanceledOnTouchOutside(false);
        NewAPIManager.getInstance().getLogisticsAPI().getBiddingOrderDetails(isOwner, no).enqueue(new Callback<BaseEntity<BiddingOrderDetailsEntity>>() {
            @Override
            public void onResponse(Call<BaseEntity<BiddingOrderDetailsEntity>> call, Response<BaseEntity<BiddingOrderDetailsEntity>> response) {
                DialogHelper.dismissProgressDialog();
                if (response.body() == null || response.body().getState() == null || response.body().getCode() == null) {
                    return;
                }
                //报价成功
                if (response.body().getState().equals(APIManager.RESPONSE_OK)) {
                    detailsLD.postValue(response.body().getData());
                }
            }

            @Override
            public void onFailure(Call<BaseEntity<BiddingOrderDetailsEntity>> call, Throwable t) {
                DialogHelper.dismissProgressDialog();
                MToast.showToast(context, t.getMessage());
            }
        });

    }

    /**
     * 加载地图信息
     *
     * @param orderEntity
     * @param aMap
     */
    public void loadMapInfo(BiddingOrderDetailsEntity orderEntity, AMap aMap) {
        this.orderEntity = orderEntity;
        this.aMap = aMap;
        aMap.clear();
        latLngs.clear();

        if (orderEntity.getLongitude() > 0 && orderEntity.getLatitude() > 0) {
            LatLng driverPosition = new LatLng(orderEntity.getLatitude(), orderEntity.getLongitude());
            addressPointList.add(new AddressItem(BiddingOrderDetailsActivity.POSITION_CARRIER, "", orderEntity.getAddress(),
                    R.mipmap.icon_sj, orderEntity.getLatitude(), orderEntity.getLongitude(), R.mipmap.icon_sj, R.mipmap.icon_sj));
            latLngs.add(driverPosition);
        }

        //显示司机的当前位置

        setPlanRouteInfo();

        aMap.setOnMarkerClickListener(marker -> {
            if (marker.getObject() != null) {
                AddressItem item = (AddressItem) marker.getObject();
                for (int i = 0; i < bundles.size(); i++) {
                    if (item.getPosition() == i) {
                        ldCurrAddress.postValue(bundles.get(i));
//                        if (bundles.get(i).isBigMarkView()) {
//                            setMarkStyle(i, marker, false);
//                            ldCurrAddress.postValue(null);
//                        } else {
//                            setMarkStyle(i, marker, true);
//                            ldCurrAddress.postValue(bundles.get(i));
//                        }
//                        if (lastPosition != i) {
//                            resetMarker(false);
//                        }
//                        markerLast = marker;
//                        lastPosition = i;
                        break;
                    }
                }
            }
            return false;
        });
    }

    /**
     * 预置路径信息
     */
    private void setPlanRouteInfo() {
        if (orderEntity == null)
            return;
        if (TextUtils.isEmpty(orderEntity.getHandleTypeNo())) {
            return;
        } else
            handleTypeNo = orderEntity.getHandleTypeNo();
        //装载 装卸地经纬度
        if (orderEntity.getPlace() != null) {
            OperateGoodsSourcePlaceVO place = orderEntity.getPlace();
            LatLonPoint sendPoint = null;
            if (place.getLatitude() > 0 && place.getLongitude() > 0) {
                sendPoint = new LatLonPoint(place.getLatitude(), place.getLongitude());
            }

            LatLonPoint viaSendPoint = null;
            if (place.getViaSendLatitude() > 0 && place.getViaSendLongitude() > 0) {
                viaSendPoint = new LatLonPoint(place.getViaSendLatitude(), place.getViaSendLongitude());
            }
            LatLonPoint viaDestPoint = null;
            if (place.getViaDestLatitude() > 0 && place.getViaDestLongitude() > 0) {
                viaDestPoint = new LatLonPoint(place.getViaDestLatitude(), place.getViaDestLongitude());
            }

            LatLonPoint destPoint = null;
            if (place.getDestLatitude() > 0 && place.getDestLongitude() > 0) {
                destPoint = new LatLonPoint(place.getDestLatitude(), place.getDestLongitude());
            }

            sourcePoints.clear();
            switch (handleTypeNo) {
                case "11":
                    sourcePoints.add(sendPoint);
                    sourcePoints.add(destPoint);
                    addressPointList.add(new AddressItem("装货点", place.getProvinceName() + place.getCityName() + place.getDistrictName(), place.getDetailAddress(), R.mipmap.icon_samll_handle, place.getLatitude(), place.getLongitude(), R.mipmap.icon_samll_handle, R.mipmap.icon_samll_handle));
                    addressPointList.add(new AddressItem(POSITION_DEST, place.getDestProvinceName() + place.getDestCityName() + place.getDestDistrictName(), place.getDestDetailAddress(), R.mipmap.icon_unload, place.getDestLatitude(), place.getDestLongitude(), R.mipmap.icon_unload, R.mipmap.icon_unload));
                    break;
                case "21":
                    sourcePoints.add(sendPoint);
                    sourcePoints.add(viaSendPoint);
                    sourcePoints.add(destPoint);
                    addressPointList.add(new AddressItem("装货点1", place.getProvinceName() + place.getCityName() + place.getDistrictName(), place.getDetailAddress(), R.mipmap.icon_samll_handle1, place.getLatitude(), place.getLongitude(), R.mipmap.icon_samll_handle1, R.mipmap.icon_samll_handle1));
                    addressPointList.add(new AddressItem("装货点2", place.getViaSendProvinceName() + place.getViaSendCityName() + place.getViaSendDistrictName(), place.getViaSendDetailAddress(), R.mipmap.icon_samll_handle2, place.getViaSendLatitude(), place.getViaSendLongitude(), R.mipmap.icon_samll_handle2, R.mipmap.icon_samll_handle2));
                    addressPointList.add(new AddressItem(POSITION_DEST, place.getDestProvinceName() + place.getDestCityName() + place.getDestDistrictName(), place.getDestDetailAddress(), R.mipmap.icon_unload, place.getDestLatitude(), place.getDestLongitude(), R.mipmap.icon_unload, R.mipmap.icon_unload));
                    break;

                case "12":
                    sourcePoints.add(sendPoint);
                    sourcePoints.add(viaDestPoint);
                    sourcePoints.add(destPoint);
                    addressPointList.add(new AddressItem("装货点", place.getProvinceName() + place.getCityName() + place.getDistrictName(), place.getDetailAddress(), R.mipmap.icon_samll_handle, place.getLatitude(), place.getLongitude(), R.mipmap.icon_samll_handle, R.mipmap.icon_samll_handle));
                    addressPointList.add(new AddressItem("卸货点1", place.getViaDestProvinceName() + place.getViaDestCityName() + place.getViaDestDistrictName(), place.getViaDestDetailAddress(), R.mipmap.icon_unload1, place.getViaDestLatitude(), place.getViaDestLongitude(), R.mipmap.icon_unload1, R.mipmap.icon_unload1));
                    addressPointList.add(new AddressItem(POSITION_DEST, place.getDestProvinceName() + place.getDestCityName() + place.getDestDistrictName(), place.getDestDetailAddress(), R.mipmap.icon_unload2, place.getDestLatitude(), place.getDestLongitude(), R.mipmap.icon_unload2, R.mipmap.icon_unload2));
                    break;

                case "22":
                    sourcePoints.add(sendPoint);
                    sourcePoints.add(viaSendPoint);
                    sourcePoints.add(viaDestPoint);
                    sourcePoints.add(destPoint);
                    addressPointList.add(new AddressItem("装货点1", place.getProvinceName() + place.getCityName() + place.getDistrictName(), place.getDetailAddress(), R.mipmap.icon_samll_handle1, place.getLatitude(), place.getLongitude(), R.mipmap.icon_samll_handle1, R.mipmap.icon_samll_handle1));
                    addressPointList.add(new AddressItem("装货点2", place.getViaSendProvinceName() + place.getViaSendCityName() + place.getViaSendDistrictName(), place.getViaSendDetailAddress(), R.mipmap.icon_samll_handle2, place.getViaSendLatitude(), place.getViaSendLongitude(), R.mipmap.icon_samll_handle2, R.mipmap.icon_samll_handle2));
                    addressPointList.add(new AddressItem("卸货点1", place.getViaDestProvinceName() + place.getViaDestCityName() + place.getViaDestDistrictName(), place.getViaDestDetailAddress(), R.mipmap.icon_unload1, place.getViaDestLatitude(), place.getViaDestLongitude(), R.mipmap.icon_unload1, R.mipmap.icon_unload1));
                    addressPointList.add(new AddressItem(POSITION_DEST, place.getDestProvinceName() + place.getDestCityName() + place.getDestDistrictName(), place.getDestDetailAddress(), R.mipmap.icon_unload2, place.getDestLatitude(), place.getDestLongitude(), R.mipmap.icon_unload2, R.mipmap.icon_unload2));
                    break;
            }
            planningLoadingRoute(sourcePoints, 1);
        }
    }

    /**
     * 添加需要规划的路线数据，并开启异步查询
     *
     * @param points 路线连接点
     * @param type   规划路线的类型：1——计划，2——实际
     */
    public void planningLoadingRoute(List<LatLonPoint> points, int type) {
        //路线点不能少于两个
        if (points == null || points.size() < 2) {
            return;
        }
        List<LatLonPoint> passedByPoints = null;
        //设置开始位置坐标点(注意经纬度不能写反,会报错1800(只能规划到中国区域里的地图路线))
        LatLonPoint startPoint = points.get(0);
        //设置目的地坐标点
        LatLonPoint endPoint = points.get(points.size() - 1);
        //查询信息对象
        RouteSearch.FromAndTo fromAndTo = new RouteSearch.FromAndTo(startPoint, endPoint);

        if (points.size() > 2) {
            passedByPoints = new ArrayList<>();
            for (int i = 1; i < points.size() - 1; i++) {
                passedByPoints.add(points.get(i));
            }
        }
        //设置搜索参数 1.fromAndTo 路径的起点终点  2.路径规划的策略（可选），默认为“躲避拥堵” 3.途经点，可选 4.避让区域，可选， 5.货车大小 ,默认轻型车
        RouteSearch.DriveRouteQuery query = new RouteSearch.DriveRouteQuery(
                fromAndTo,
                RouteSearch.DRIVING_SINGLE_SHORTEST,
                passedByPoints,
                null,
                "");

        if (type == 1) {
            if (planRouteSearch == null)
                planRouteSearch = new RouteSearch(context);
            // 搜索监听
            planRouteSearch.setRouteSearchListener(new OnPlanListener());
            //开始异步查询
            planRouteSearch.calculateDriveRouteAsyn(query);
        }
    }

    private void addMarkers() {
        bundles.clear();
        markers.clear();
        markers.clear();
        for (int i = 0; i < addressPointList.size(); i++) {
            AddressItem entity = addressPointList.get(i);
            entity.setPosition(i);
            bundles.add(entity);
            LatLng latLng = new LatLng(entity.getLatitude(), entity.getLongitude());
            MarkerEntity markerEntity = new MarkerEntity(latLng, entity.getMakerIcon());
            Marker marker = aMap.addMarker(mapMarkerTools.getMarkerOptions(markerEntity));
            marker.setObject(entity);
            markers.add(marker);
        }

        //显示完整地图路线
        LatLngBounds.Builder builder = new LatLngBounds.Builder();
        for (int i = 0; i < latLngs.size(); i++) {
            builder.include(latLngs.get(i));
        }
        //显示全部路径点,第二个参数是四周留空宽度
        aMap.moveCamera(CameraUpdateFactory.newLatLngBounds(builder.build(), 100));
    }

    /**
     * 路线规划回调类
     */
    private class OnPlanListener implements RouteSearch.OnRouteSearchListener {

        @Override
        public void onBusRouteSearched(BusRouteResult busRouteResult, int i) {

        }

        @Override
        public void onDriveRouteSearched(DriveRouteResult result, int code) {
            if (code == 1000 && result != null && result.getPaths() != null && result.getPaths().size() > 0) {
                if (aMap == null) {
                    return;
                }

                List<DrivePath> paths = result.getPaths();
                //创建存储坐标点的集合
                List<LatLonPoint> latLonPoints = new ArrayList<>();
                List<LatLng> planLatLngs = new ArrayList<>();

                //遍历获取规划的所有路线坐标点
                for (DriveStep mDriveStep : paths.get(0).getSteps()) {
                    for (LatLonPoint mLatLonPoint : mDriveStep.getPolyline()) {
                        latLonPoints.add(mLatLonPoint);
                        latLngs.add(new LatLng(mLatLonPoint.getLatitude(), mLatLonPoint.getLongitude()));
                        planLatLngs.add(new LatLng(mLatLonPoint.getLatitude(), mLatLonPoint.getLongitude()));
                    }
                }

                //带纹理纯色路线
                aMap.addPolyline(new PolylineOptions()
                        //路线坐标点的集合
                        .addAll(planLatLngs)
                        //线的宽度
                        .width(20)
                        .setCustomTexture(BitmapDescriptorFactory.fromResource(R.drawable.icon_path_gray))
                );

                //添加所有marker
                addMarkers();

                //显示完整地图路线
                LatLngBounds.Builder builder = new LatLngBounds.Builder();
                for (int i = 0; i < latLngs.size(); i++) {
                    builder.include(latLngs.get(i));
                }
                //显示全部路径点,第二个参数是四周留空宽度
                aMap.moveCamera(CameraUpdateFactory.newLatLngBounds(builder.build(), 100));
                ldMapLoadFinish.postValue(true);
            }
        }

        @Override
        public void onWalkRouteSearched(WalkRouteResult walkRouteResult, int i) {

        }

        @Override
        public void onRideRouteSearched(RideRouteResult rideRouteResult, int i) {

        }

    }

    /**
     * 根据城市区域查询经纬度
     */
    public void getLocation(Context context, String address) {
        if (TextUtils.isEmpty(address))
            return;
        GeocodeSearch geocodeSearch = new GeocodeSearch(context);
        geocodeSearch.setOnGeocodeSearchListener(new GeocodeSearch.OnGeocodeSearchListener() {
            @Override
            public void onRegeocodeSearched(RegeocodeResult regeocodeResult, int code) {

            }

            @Override
            public void onGeocodeSearched(GeocodeResult geocodeResult, int code) {
                if (code != 1000) return;
                if (geocodeResult != null && geocodeResult.getGeocodeAddressList() != null &&
                        geocodeResult.getGeocodeAddressList().size() > 0) {
                    GeocodeAddress geocodeAddress = geocodeResult.getGeocodeAddressList().get(0);
                    double latitude = geocodeAddress.getLatLonPoint().getLatitude();//纬度
                    double longitude = geocodeAddress.getLatLonPoint().getLongitude();//经度
                    //回调UI
                    ldLatLng.postValue(new LatLng(latitude, longitude));
                } else {
                    MToast.showToast(getApplication(), "地址名出错");
                }
            }
        });
        GeocodeQuery geocodeQuery = new GeocodeQuery(address, "");
        geocodeSearch.getFromLocationNameAsyn(geocodeQuery);
    }

}
